package cn.shengongying.utils;

import cn.shengongying.exception.DigestException;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;

/**
 * author: RXK
 * date: 2022/1/6 星期四
 * desc:
 */
public class AesUtils {

    private AesUtils() {
    }

    private static final String KEY_ALGORITHM = "AES";
    private static final String DEFAULT_CIPHER_ALGORITHM = "AES/CBC/PKCS5Padding";//加密算法
    private static final byte[] IV = "!@#$shengongying".getBytes(); //初始化向量

    /**
     * AES 解密操作
     *
     * @param content 待解密内容
     * @param key 加密密钥
     * @return 解密数据
     * */
    public static String geTuiDecrypt(String content, String key) throws DigestException {
        try {
            Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
            IvParameterSpec ivSpec = new IvParameterSpec(IV);
            cipher.init(Cipher.DECRYPT_MODE, getSecretKey(key), ivSpec);
            byte[] result = cipher.doFinal(hex2Bytes(content));
            return new String(result, StandardCharsets.UTF_8);
        } catch (Exception e) {
            throw new DigestException("解密出现异常:{"+e.getMessage()+"}");
        }
    }

    public static String encrypt(String phone,String key) throws DigestException {
        try {
            Cipher instance = Cipher.getInstance(KEY_ALGORITHM);
            byte[] bytes = Base64.getDecoder().decode(key);
            SecretKeySpec secretKeySpec = new SecretKeySpec(bytes, KEY_ALGORITHM);
            instance.init(Cipher.ENCRYPT_MODE,secretKeySpec);
            byte[] doFinal = instance.doFinal(phone.getBytes(StandardCharsets.UTF_8));
            return Base64.getEncoder().encodeToString(doFinal);
        } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException  e) {
            throw new DigestException("加密出现异常：{" + e.getMessage() + "}");
        }
    }

    public static String decrypt(String content,String key) throws DigestException {
        byte[] decode = Base64.getDecoder()
                .decode(content);
        try {
            Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
            byte[] bytes = Base64.getDecoder().decode(key);
            SecretKeySpec keySpec = new SecretKeySpec(bytes, KEY_ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE,keySpec);
            byte[] doFinal = cipher.doFinal(decode);
            return new String(doFinal, StandardCharsets.UTF_8);
        } catch (NoSuchAlgorithmException | NoSuchPaddingException | IllegalBlockSizeException | InvalidKeyException | BadPaddingException e) {
            throw new DigestException("解密出现异常：{" + e.getMessage() + "}");
        }
    }

    /**
     * 获取密钥,取前16位,不足则复制
     *
     * @param key 用户密钥
     * @return KeySpec对象
     * */
    private static SecretKeySpec getSecretKey(String key) {
        if(key==null || key.isEmpty()){
            return null;
        }
        StringBuilder s = new StringBuilder(key);
        while(s.length() < 16){
            s.append(key);
        }
        return new SecretKeySpec(s.substring(0,16).getBytes(), KEY_ALGORITHM);
    }

    /**
     * hex字符串转byte数组
     *
     * @param hex 待转换的hex字符串
     * @return  转换后的byte数组
     * */
    private static byte[] hex2Bytes(String hex){
        if (hex.length() % 2 == 1){
            hex="0" + hex;
        }
        byte[] result = new byte[hex.length()/2];
        for (int i = 0; i < result.length; i++){
            result[i] = (byte)Integer.parseInt(hex.substring(2*i,2*i+2), 16);
        }
        return result;
    }

}
